package com.telit.firecommand.facade;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.telit.common.constant.RoleCodeConstants;
import com.telit.common.core.utils.FeignUtils;
import com.telit.common.entity.DataReturn;
import com.telit.common.enums.ResultCode;
import com.telit.common.exception.ForestBaseException;
import com.telit.common.util.LanguageUtils;
import com.telit.communicate.dto.SendMessageDTO;
import com.telit.communicate.feign.RemoteCommunicateService;
import com.telit.firecommand.dto.FirePushAlarmsDTO;
import com.telit.upms.dto.DynamicParamsForQueryUserDto;
import com.telit.upms.feign.RemoteUpmsService;
import com.telit.upms.vo.MicroSysDistrictVo;
import com.telit.upms.vo.MicroSysUserAllInfoVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Component
@RequiredArgsConstructor
@Slf4j
public class MsgFireTriggerFacadeService {


    private final ApplicationContext applicationContext;

    private final RemoteCommunicateService communicateFeignClient;

    private final RemoteUpmsService remoteUpmsService;


    public void pushMsg(FirePushAlarmsDTO entity) {

       pushWebSocket(JSONUtil.toJsonStr(entity));
        log.info("火情预警开始发送socker消息");
    }

    @Async
    @EventListener
    @SuppressWarnings("all")
    public void pushWebSocket(String msg) {
        final TimeInterval timeInterval = DateUtil.timer();

        final FirePushAlarmsDTO firePushAlarmsDTO = JSONUtil.toBean(msg, FirePushAlarmsDTO.class);
        if (ObjectUtil.isNull(firePushAlarmsDTO)) {
            log.error("websocket推送失败,火情信息解析失败:msg[{}]", msg);
            return;
        }
        //获取websocket 推送内容
        final SendMessageDTO wsDto = buildDtoForWebSocket(firePushAlarmsDTO);
        try {
            if (ObjectUtil.isNotNull(wsDto)) {
                final DataReturn dr = communicateFeignClient.sendMsg(wsDto);
            }
        } catch (Exception e) {
            log.error("微服务内部错误：websocket推送失败!msg:[{}],dr:[{}]", msg, e.getMessage());
        }
    }

    /**
     * 构造websocket 推送对象
     *
     * @return 构造的dto对象
     */
    private SendMessageDTO buildDtoForWebSocket(FirePushAlarmsDTO entity) {
//        FireTransferReportVO fireTransferReportVO = new FireTransferReportVO();
//        BeanUtils.copyProperties(entity,fireTransferReportVO);
//        fireTransferReportVO.setTransferStatusStr(TransgerReportStatus.code2Str(entity.getTransferStatus()));
        //根据转交下发流转的待处理人的行政区划code查询对应的账号id集合
        final List<Long> fireMangerIdList = CollUtil.<Long>newArrayList();
        if (entity.getAreaCode() != null) {
            fireMangerIdList.addAll(fireMangerIdListByDistrictCode(entity.getAreaCode()));
        } else {
            fireMangerIdList.addAll(fireMangerIdListByDistrictCode(entity.getAreaCode()));
        }
        //将自己排除
//        if (fireMangerIdList != null && fireMangerIdList.size() > 0) {
//            Iterator<String> iterator = fireMangerIdList.iterator();
//            while (iterator.hasNext()){
//                if (iterator.next().equals(JwtTokenUtils.getId())){
//                    iterator.remove();
//                }
//            }
//        }

        if (fireMangerIdList != null && fireMangerIdList.size() > 0) {
            //构造消息体
            return new SendMessageDTO("WEBWITHINUSERID", Convert.toStrArray(fireMangerIdList),
                    JSON.toJSONString(DataReturn.ok(entity.getFlag(), entity)));
        } else {
            return null;
        }
    }


    private List<Long> fireMangerIdListByDistrictCode(String districtCode) {
        //通过多维度code查询对应人员信息发送消息
        List<String> codes = new ArrayList<>();
        if (StringUtils.isNotBlank(districtCode)) {
            codes.add(districtCode);
            if (districtCode.length() > 6) {
                codes.add(districtCode.substring(0, 6));
                codes.add(districtCode.substring(0, 4));
            }
        }
        //根据行政区划编码查询行政区划ID
        com.telit.common.core.utils.Result<Map<String, MicroSysDistrictVo>> selectDistrictDetailByListCodesResult = remoteUpmsService.selectDistrictDetailByListCodes(
                codes);
        Map<String, MicroSysDistrictVo> microSysDistrictVoMap = FeignUtils.unwrap(
                selectDistrictDetailByListCodesResult);
        List<Long> areaIds = new ArrayList<>();
        for (String code : codes) {
            MicroSysDistrictVo microSysDistrictVo = microSysDistrictVoMap.get(code);
            if (microSysDistrictVo == null) {
                throw new ForestBaseException(LanguageUtils.codeMessage(ResultCode.OPERATE_ERROR.getCode()));
            }
            areaIds.add(microSysDistrictVo.getId());

        }
        List<Long> userLists = new ArrayList<>();
        for (Long areaId : areaIds) {
            DynamicParamsForQueryUserDto dynamicParamsForQueryUserDto = DynamicParamsForQueryUserDto.builder()
                    .page(JSONUtil.toJsonStr(new Page<>(1, 100)))
                    .roleId(RoleCodeConstants.ROLE_CODE_FIRE_MANAGER_ID)//2023-01-10：由于统一平台不支持通过角色码查询，只能固定角色ID查询
                    .areaId(areaId)//行政区划Id
                    .areaRecursion(false)//是否开启行政区划递归往下搜索
                    .build();
            com.telit.common.core.utils.Result<Page<MicroSysUserAllInfoVo>> selectUserContainDeptAndRoleForPageSupportOrderResult = remoteUpmsService.selectUserContainDeptAndRoleForPageSupportOrder(
                    dynamicParamsForQueryUserDto);
            Page<MicroSysUserAllInfoVo> microSysUserAllInfoVoPage = FeignUtils.unwrap(
                    selectUserContainDeptAndRoleForPageSupportOrderResult);

            microSysUserAllInfoVoPage.getRecords().stream()
                    .forEach(microSysUserAllInfoVo -> {
                        userLists.add(microSysUserAllInfoVo.getId());
                    });

        }
        return userLists;
    }

}
